using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using HappyFrogXna.Level;
using HappyFrogXna.DrawingSystem;
using HappyFrogXna.ScreenSystem;
using Microsoft.Xna.Framework.Graphics;
using FarseerPhysics.Factories;
using HappyFrogXna.Miscellaneous;
using System.Diagnostics;

namespace HappyFrogXna.Roles
{
    enum EntityType
    {
        Frog,
        Animal,
        Wood,
        Ice,
        Stone
    }

    class EntityUserData
    {
        public string Name { get; set; }
        public EntityType Type { get; set; }
        public float HealthPoint { get; set; }
        public bool Killed { get; set; }

        public EntityUserData()
        {
            Killed = false;
        }

        public EntityUserData Clone()
        {
            EntityUserData userDataCopy = new EntityUserData();
            userDataCopy.Name = this.Name;
            userDataCopy.Type = this.Type;
            userDataCopy.HealthPoint = this.HealthPoint;
            return userDataCopy;
        }
    }

    class Entity
    {
        protected World _world;
        protected float _scaleRadio;

        public Sprite EntitySprite { set; get; }
        public Body EntityBody { set; get; }

        public EntityUserData UserDate 
        {
            get { return (Body.UserData as EntityUserData); }
            set { Body.UserData = value; }
        }

        public Body Body
        {
            protected set { EntityBody = value; }
            get { return EntityBody; }
        }

        // positon of body
        public Vector2 Position
        {
            set { EntityBody.Position = value; }
            get { return EntityBody.Position; }
        }
        // rotation of body
        public float Rotation
        {
            set { EntityBody.Rotation = value; }
            get { return EntityBody.Rotation; }
        }

        public bool IsVisible { set; get; }
        public bool IsActive
        {
            get { return EntityBody.Enabled; }
            set { EntityBody.Enabled = value; }
        }

        public Texture2D Texture
        {
            get { return EntitySprite.Texture; }
        }

        private Vector2 _originalPos;
        public Vector2 OriginalPos
        {
            get { return _originalPos; }
        }

        public Entity(World w, Vector2 pos)
        {
            _world = w;
            _originalPos = pos;
            _scaleRadio = ScaleRadioDisplayOnScreen;
        }

        public virtual void RemoveMe()
        {
            this.Body.Awake = false;
            this.IsActive = false;
            this.IsVisible = false;
        }

        public virtual Entity Clone()
        {
            return null;
        }

        /// <summary>
        /// test whether a position is touched the entity
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public virtual bool IsTouched(Vector2 pos, float extend)
        {
            return false;
        }

        public virtual bool IsMoving(float sceneGroundWidthInSim)
        {
            if (Position.X > sceneGroundWidthInSim || Position.X < 0)
            {
                return false;
            }
            //return GameMathHelper.DistanceOfPos(LastPositions[LastPositions.Count - 1], Position) > 0.1;
            return (Body.LinearVelocity.Length() > 0.5f || Body.AngularVelocity > 0.3f);
        }

        public virtual void Update(GameTime gameTime)
        { }

        /// <summary>
        /// the scale radio when entity displaied on entity component selector.
        /// </summary>
        /// <returns></returns>
        public virtual float ScaleRadioOnComponentSelector
        {
            get
            {
                return 0.8f;
            }
        }

        /// <summary>
        /// the scale radio when entity displaied on game sceeen
        /// </summary>
        /// <returns></returns>
        public virtual float ScaleRadioDisplayOnScreen
        {
            get
            {
                return 1.0f;
            }
        }
    }
}
